#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys
import platform
import shutil
from typing import List, Optional, Tuple

class Utils:
    """工具函数类"""
    
    @staticmethod
    def get_file_size_str(size_in_bytes: int) -> str:
        """
        将字节大小转换为人类可读的字符串
        
        Args:
            size_in_bytes: 文件大小（字节）
            
        Returns:
            格式化后的大小字符串
        """
        # 定义单位
        units = ['B', 'KB', 'MB', 'GB', 'TB']
        
        # 转换逻辑
        unit_index = 0
        size = float(size_in_bytes)
        
        while size >= 1024 and unit_index < len(units) - 1:
            size /= 1024
            unit_index += 1
        
        # 格式化输出
        if unit_index == 0:
            return f"{int(size)} {units[unit_index]}"
        else:
            return f"{size:.2f} {units[unit_index]}"
    
    @staticmethod
    def get_file_info(file_path: str) -> Tuple[str, str, str]:
        """
        获取文件信息
        
        Args:
            file_path: 文件路径
            
        Returns:
            (文件名, 文件大小字符串, 文件类型)
        """
        try:
            file_name = os.path.basename(file_path)
            file_size = os.path.getsize(file_path)
            file_size_str = Utils.get_file_size_str(file_size)
            
            # 获取文件类型
            if os.path.isdir(file_path):
                file_type = "文件夹"
            else:
                # 获取扩展名
                _, ext = os.path.splitext(file_path)
                if ext:
                    file_type = ext[1:].upper()  # 去掉点号
                else:
                    file_type = "未知"
            
            return file_name, file_size_str, file_type
        except Exception:
            return os.path.basename(file_path), "未知", "未知"
    
    @staticmethod
    def ensure_dir_exists(dir_path: str) -> None:
        """
        确保目录存在，如果不存在则创建
        
        Args:
            dir_path: 目录路径
        """
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
    
    @staticmethod
    def get_default_output_dir() -> str:
        """
        获取默认输出目录
        
        Returns:
            默认输出目录路径
        """
        # 根据操作系统获取合适的目录
        if platform.system() == "Windows":
            return os.path.join(os.path.expanduser("~"), "Documents")
        else:  # macOS, Linux等
            return os.path.join(os.path.expanduser("~"), "Downloads")
    
    @staticmethod
    def get_temp_dir() -> str:
        """
        获取临时目录
        
        Returns:
            临时目录路径
        """
        temp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "temp")
        Utils.ensure_dir_exists(temp_dir)
        return temp_dir
    
    @staticmethod
    def clean_temp_dir() -> None:
        """清理临时目录"""
        temp_dir = Utils.get_temp_dir()
        if os.path.exists(temp_dir):
            shutil.rmtree(temp_dir)
            Utils.ensure_dir_exists(temp_dir)
    
    @staticmethod
    def resource_path(relative_path: str) -> str:
        """
        获取资源文件的绝对路径（用于PyInstaller打包后的资源访问）
        
        Args:
            relative_path: 相对路径
            
        Returns:
            资源文件的绝对路径
        """
        try:
            # PyInstaller创建临时文件夹，将路径存储在_MEIPASS中
            base_path = sys._MEIPASS
        except Exception:
            base_path = os.path.abspath(".")
        
        return os.path.join(base_path, relative_path)
    
    @staticmethod
    def is_valid_directory(path: str) -> bool:
        """
        检查路径是否为有效目录
        
        Args:
            path: 要检查的路径
            
        Returns:
            是否为有效目录
        """
        return os.path.exists(path) and os.path.isdir(path)
    
    @staticmethod
    def get_common_parent_dir(paths: List[str]) -> str:
        """
        获取多个路径的共同父目录
        
        Args:
            paths: 路径列表
            
        Returns:
            共同父目录
        """
        if not paths:
            return ""
        
        # 将所有路径转换为绝对路径
        abs_paths = [os.path.abspath(p) for p in paths]
        
        # 分割路径
        parts_list = [p.split(os.sep) for p in abs_paths]
        
        # 找到共同前缀
        common_parts = []
        for parts in zip(*parts_list):
            if len(set(parts)) == 1:  # 所有路径在这一级都相同
                common_parts.append(parts[0])
            else:
                break
        
        # 构建共同父目录
        if common_parts:
            return os.sep.join(common_parts)
        else:
            # 如果没有共同部分，返回根目录
            return os.sep
    
    @staticmethod
    def suggest_archive_name(paths: List[str], format_ext: str) -> str:
        """
        根据选择的文件/文件夹，建议一个合适的压缩文件名
        
        Args:
            paths: 要压缩的文件/文件夹路径列表
            format_ext: 压缩格式扩展名（如.zip）
            
        Returns:
            建议的压缩文件名
        """
        if not paths:
            return f"archive{format_ext}"
        
        if len(paths) == 1:
            # 单个文件/文件夹，使用其名称
            base_name = os.path.basename(paths[0])
            return f"{base_name}{format_ext}"
        else:
            # 多个文件/文件夹，使用共同父目录名称或默认名称
            parent_dir = Utils.get_common_parent_dir(paths)
            dir_name = os.path.basename(parent_dir)
            
            if dir_name:
                return f"{dir_name}{format_ext}"
            else:
                return f"archive{format_ext}"